﻿package igz.fleaxy.ui
{
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.filters.BevelFilter;
	import igz.fleaxy.ui.text.LabelUi;
	import igz.fleaxy.util.FilterType;
	import igz.fleaxy.util.ObjectUtil;
	
	/**
	 * @author Pedro Sánchez Aparicio - pedro.sanchez@intelygenz.com [www.Intelygenz.com]
	 */
	public class ButtonUi extends Sprite
	{
		static public const $ACTION_TYPE_NONE 	  : uint = 0;
		static public const $ACTION_TYPE_NORMAL   : uint = 1;
		static public const $ACTION_TYPE_MAIN     : uint = 2;
		static public const $ACTION_TYPE_CRITICAL : uint = 3;
		
		static public var $COLOR_TYPE_NORMAL   : uint = 0xCCCCCC;
		static public var $COLOR_TYPE_MAIN     : uint = 0x088A08;
		static public var $COLOR_TYPE_CRITICAL : uint = 0xDF0101;
		
		public var $INITIAL_FILTERS : Array = [ new BevelFilter(2, 45, 0xFFFFFF, 0.3, 0, 0.3, 3, 3) ];
		public var $DOWN_FILTERS	: Array = [ new BevelFilter(2, 215, 0xFFFFFF, 0.3, 0, 0.3, 3, 3) ];
		
		protected var _Action:Function;
		
		protected var _Bg : Sprite;
		protected var _FxLayer : Sprite;
		
		protected var _Label : LabelUi;
		
		
		protected var _Icon : DisplayObject;
		
		protected var _Settings:Object = { "marginTop"      : 2
										  ,"marginLeft"     : 3
										  ,"marginInternal"	: 2
										  ,"round"          : 3
										  ,"labelStyle"     : ""
										  ,"background"     : 0xB6BBB0
										  ,"backgroundAlpha": 1
										  ,"icon"			: null
										  ,"actionType"		: ButtonUi.$ACTION_TYPE_NONE
										  ,"border" 		: 0x000000
										  ,"borderThickness": 1
										  ,"borderAlpha"	: 1
										  ,"width"          : null
										  ,"labelSettings"  : null
										};
		
		/**
		 * Componente botón
		 *
		 * @param	p_label   String
		 * @param	f_action  Función ejecutada al hacer click
		 * @param	p_settings {   "marginTop"      : 2
								  ,"marginLeft"     : 3
								  ,"marginInternal"	: 2
								  ,"round"          : 3
								  ,"labelStyle"     : ""
								  ,"background"     : 0xB6BBB0
								  ,"backgroundAlpha": 1
								  ,"icon"			: null
								  ,"actionType"		: ButtonUi.$ACTION_TYPE_NONE
								  ,"border" 		: 0x000000
								  ,"borderThickness": 1
								  ,"borderAlpha"	: 1
								  ,"width"          : null
								  ,"labelSettings"  : null
								}
		 *
		 * @example
		 *
		 * var boton:ButtonUI = new ButtonUi ( "Continuar", f_acccion, { "marginTop" : 10, "marginLeft" : 25 } );
		 *
		 * addChild( boton );
		 *
		 */
		public function ButtonUi ( p_text:String, f_action:Function, p_settings:Object=null ) {
			ObjectUtil.$Merge( p_settings, _Settings );
			
			_Bg = new Sprite();
			addChild( _Bg );
			
			_Label = new LabelUi( p_text, _Settings["labelStyle"], _Settings["labelSettings"] );
			_Label.mouseEnabled = false;
			this.addChild( _Label );
			
			_Action = f_action;
			
			if ( _Settings["icon"] != null && _Settings["icon"] is DisplayObject ) {
				_Icon = _Settings["icon"];
				this.addChild( _Icon );
			}
			
			_FxLayer = new Sprite();
			//_FxLayer.blendMode = BlendMode.SUBTRACT;
			//this.addChild( _FxLayer );
			
			this.tabEnabled = false;
			this.filters = $INITIAL_FILTERS;
			
			$Enable();
			
			_Draw();
		}
		
		protected function _OnMouseClick( p_event:MouseEvent ) : void {
			_Action();
		}
		
		private function _OnMouseDown ( p_event:MouseEvent ) : void {
			p_event.stopPropagation();
			_Down();
		}
		
		private function _OnMouseUp ( p_event:MouseEvent ) : void {
			_Up();
		}
		
		private function _OnMouseOver( p_event:MouseEvent ):void
		{
			_Over();
		}
		
		private function _OnMouseOut ( p_event:MouseEvent ) : void {
			_Out();
		}
		
		protected function _Down () : void {
			filters = $DOWN_FILTERS;
		}
		
		protected function _Up () : void {
			filters = $INITIAL_FILTERS;
		}
		
		protected function _Over () : void {
			
		}

		protected function _Out () : void {
			filters = $INITIAL_FILTERS;
		}
		
		protected function _Draw () : void {
			_DrawBg();
			_DrawFxLayer();
		}
		
		/*
		 * Dibuja el botón
		 */
		protected function _DrawBg () : void {
			//Recolocamos los elementos _Icon y _Label
			_Recolocate();
			
			var BgWidth:int = ( _Settings["width"] != null ) ? _Settings["width"] : _Settings["marginLeft"] * 2 + ( (_Label.text!="")? _Label.width : 0 );
			var BgHeight:int = _Label.height + _Settings["marginTop"] * 2;

			if ( _Icon != null ) {
				BgWidth += _Icon.width + _Settings["marginInternal"];
				BgHeight = _Settings["marginTop"] * 2 + Math.max(_Label.height, _Icon.height);
			}

			_Bg.graphics.clear();
			
			var marginBorder : Number = 0;
			if ( _Settings["border"] != null ) {
				marginBorder = _Settings["borderThickness"] / 2;
				_Bg.graphics.lineStyle( _Settings["borderThickness"], _Settings["border"], _Settings["borderAlpha"], true );
			}
			_Bg.graphics.beginFill( _Settings["background"], _Settings["backgroundAlpha"]);
			_Bg.graphics.drawRoundRect( marginBorder
									  , marginBorder+1
									  , BgWidth - _Settings["borderThickness"]
									  , BgHeight - _Settings["borderThickness"]
									  , _Settings["round"]
									  , _Settings["round"] 
									  );
			_Bg.graphics.endFill();
		}
		
		/*
		 * Añade una capa de efecto o color sobre el Botón una vez dibujado.
		 */
		protected function _DrawFxLayer () : void {
			if ( _Settings["actionType"] != $ACTION_TYPE_NONE ) {
				var actionColor : uint;
				switch ( _Settings["actionType"] ) {
					case $ACTION_TYPE_NORMAL:
						actionColor = $COLOR_TYPE_NORMAL;
						break;
					case $ACTION_TYPE_MAIN:
						actionColor = $COLOR_TYPE_MAIN;
						break;
					case $ACTION_TYPE_CRITICAL:
						actionColor = $COLOR_TYPE_CRITICAL;
						break;
						
				}
				
				_FxLayer.graphics.clear();
				_FxLayer.graphics.beginFill( actionColor, 0.1 );
				_FxLayer.graphics.drawRoundRect( 0, 0, this.width, this.height, _Settings["round"], _Settings["round"]);
				_FxLayer.graphics.endFill();
			}
		}
		
		/*
		 * Reajusta la posición de los elementos _Icon y _Label dentro del botón
		 */
		protected function _Recolocate () : void {
			if ( _Icon != null ) {
				if ( _Icon.height > _Label.height ) {
					_Icon.y = _Settings["marginTop"];
					_Label.y = _Settings["marginTop"] + (_Icon.height - _Label.height)/2;
				}
				else {
					_Label.y = _Settings["marginTop"];
					_Icon.y = _Settings["marginTop"] + (_Label.height - _Icon.height)/2;
				}
				_Icon.x = _Settings["marginLeft"];
				_Label.x = _Icon.x + _Icon.width + _Settings["marginInternal"];
			}
			else {
				_Label.x = _Settings["marginLeft"];
				_Label.y = _Settings["marginTop"];
			}
		}
		
		public function $Enable () : void {
			useHandCursor = true;
			buttonMode    = true;
			mouseEnabled  = true;
			alpha   	   = 1;
			filters = $INITIAL_FILTERS;
			
			
			addEventListener( MouseEvent.CLICK, _OnMouseClick );
			addEventListener( MouseEvent.MOUSE_DOWN, _OnMouseDown );
			addEventListener( MouseEvent.MOUSE_UP, _OnMouseUp );
			addEventListener( MouseEvent.ROLL_OVER, _OnMouseOver );
			addEventListener( MouseEvent.ROLL_OUT, _OnMouseOut );
		}
		
		public function $Disable () : void {
			useHandCursor = false;
			buttonMode    = false;
			mouseEnabled  = false;
			alpha   	   = 0.7;
			filters = [ FilterType.$GRAYSCALE ];

			removeEventListener( MouseEvent.CLICK, _OnMouseClick );
			removeEventListener( MouseEvent.MOUSE_DOWN, _OnMouseDown );
			removeEventListener( MouseEvent.MOUSE_UP, _OnMouseUp );
			removeEventListener( MouseEvent.ROLL_OVER, _OnMouseOver );
			removeEventListener( MouseEvent.ROLL_OUT, _OnMouseOut );
		}
		
		
		/**
		 * Icono que se insertará en el botón
		 */
		public function set $Icon( p_iconBitmap: DisplayObject ) : void {
			if ( _Icon != null ) {
				this.removeChild( _Icon );
			}
			
			_Icon = p_iconBitmap;
			this.addChild( _Icon );

			_Draw();
		}
		public function get $Icon () : DisplayObject {
			return _Icon;
		}
		
		/*
		 * Asocia una acción al botón
		 *
		 * @param	p_function Acción que se ejecutará cuando se indique.
		 */
		public function set $Action( p_function: Function ) : void {
			_Action = p_function;
		}
		
		public function set htmlText ( p_text:String ) : void {
			_Label.text = p_text;
		}
		
		public function get htmlText () : String {
			return _Label.text;
		}
		


	}
	
}